from flask import session,render_template,current_app,jsonify,request,g

from . import news_blue

from info.models import User,Category,News

from info.utils.response_code import RET

from info import constants,db

from info.utils.commons import login_required



@news_blue.route('/')
@login_required
def index():

    # # 1,使用模板加载项目首页，在info添加静态文件夹
    #
    # user_id=session.get('user_id')
    # # 根据user_id查询mysql数据库
    # user=None
    # if user_id:
    #     try:
    #         user=User.query.get(user_id)
    #     except Exception as e:
    #         current_app.logger.error(e)


    user=g.user
    # 加载新闻分类

    try:
        categories=Category.query.all()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg='查询分类数据失败')
    # 判断查询结果
    if not categories:
        return jsonify(errno=RET.NODATA,errmsg='无文件分类数据')
    # 遍历查询结果，调用模型类中的to_dict函数，获取到字典数据
    category_list=[]

    for category in categories:
        category_list.append(category.to_dict())

    # 新闻点击排行数据加载
    try:
        news_rank=News.query.order_by(News.clicks.desc()).limit(constants.CLICK_RANK_MAX_NEWS)

    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg='查询数据排行数据失败')
    # 判断查询结果
    if not news_rank:
        return jsonify(errno=RET.NODATA,errmsg='无新闻排行数据')

    news_rank_list=[]
    for news in news_rank:
        news_rank_list.append(news.to_dict())
    # 定义字典，给模板传入用户数据
    data={
        'user_info':user.to_dict() if user else None,
        'category_list':category_list,
        'news_rank_list':news_rank_list
    }
    return render_template('news/index.html',data=data)


# 新闻列表数据加载、
@news_blue.route('/news_list')
def get_news_list():



    """
    新闻列表数据加载
    获取参数---检查参数---业务处理---返回结果
    1、获取参数
    cid，page，per_page,需要给默认值
    2、检查参数，转换参数的数据类型
    3、根据分类id查询指定分类下的新闻数据，按照新闻的发布时间倒叙排序，并且进行分页
        实现形式一：写多条查询语句
        if cid == 1:如果是最新，查询所有新闻，过滤条件为空
            News.query.filter().order_by(News.create_time.desc()).paginate(page,per_page,False)
        else:
            如果选择了不是'最新'的分类,根据分类id进行查询新闻数据
            News.query.filter(News.category_id==cid).order_by(News.create_time.desc()).paginate(page,per_page,False)
        实现形式二：写一条查询语句
        filters = []
        if cid > 1:如果不是最新，添加分类id
            filters.append(News.category_id==cid)
        News.query.filter(*filters).order_by(News.create_time.desc()).paginate(page,per_page,False)
    4、获取分页后的数据，总数据items、当前页数page、总页数pages
    5、遍历总数据，调用模型类中的to_dict函数，获取新闻的字典数据
    6、返回结果
        总数据items、当前页数page、总页数pages

    :return:
    """
    # 获取参数，get请求，args属性
    cid=request.args.get('cid','1')
    page=request.args.get('page','1')
    per_page=request.args.get('per_page','10')
    # 检查参数类型
    try:
        cid,page,per_page=int(cid),int(page),int(per_page)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.PARAMERR,errmsg='参数类型错误')

    # 定义查询数据的过滤条件
    filters=[]
    if cid>1:
        filters.append(News.category_id==cid)

    try:
        paginate=News.query.filter(*filters).order_by(News.create_time.desc()).paginate(page,per_page,False)

    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg='查询新闻列表数据失败')

    news_list=paginate.items
    total_page=paginate.pages
    current_page=paginate.page

    news_dict_list=[]
    for news in news_list:
        news_dict_list.append(news.to_dict())

    data={
        'news_dict_list':news_dict_list,
        'total_page':total_page,
        'current_page':current_page
    }
    return jsonify(errno=RET.OK,errmsg='OK',data=data)


# 新闻详情页面
@news_blue.route('/<int:news_id>')
@login_required
def news_detail(news_id):

    # user_id=session.get('user_id')
    # # 根据user_id查询mysql数据库
    # user=None
    # if user_id:
    #     try:
    #         user=User.query.get(user_id)
    #     except Exception as e:
    #         current_app.logger.error(e)

    user=g.user

    try:
        news_rank=News.query.order_by(News.clicks.desc()).limit(constants.CLICK_RANK_MAX_NEWS)

    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg='查询数据排行数据失败')

    if not news_rank:
        return jsonify(errno=RET.NODATA,errmsg='无新闻排行数据')

    news_rank_list=[]
    for news in news_rank:
        news_rank_list.append(news.to_dict())

    # 新闻点击排行
    try:
       news=News.query.get(news_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg='查询新闻详情数据失败')
    # 判断查询结果
    if not news:
        return jsonify(errno=RET.NODATA,errmsg='无新闻详情数据')
    # 新闻点击次数加1
    news.clicks+=1
    # 将点击量添加到MySQL数据库
    try:
        db.session.add(news)
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR,errmsg='保存数据失败')

    # 定义变量，用来标记收藏或者是取消收藏
    is_collected=False
    # 判断用户是否登录和是否已经收藏过该新闻
    if user and news in user.collection_news:
        is_collected=True


    # 定义字典数据，返回模板
    data={
        'user_info':user.to_dict() if user else None,

        'news_rank_list':news_rank_list,
        'news_detail':news.to_dict(),
        'is_collected':is_collected
    }
    return render_template('news/detail.html',data=data)

@news_blue.route('/news_collect',methods=['POST'])
@login_required
def user_collection():
    # 检测用户是否登录
    # 获取参数
    # 检查参数
    # 转换新闻ID的数据类型
    # 检查action参数的范围
    # 判断新闻ID查询数据库，确认新闻的存在
    # 判断用户是否收藏或者取消收藏
    # 判断用户是否收藏过
    # 收藏：user.collection_news.append(news)
    # 取消收藏：user.collection_news.remove(news)
    # 提交数据
    # 返回结果
    user=g.user
    if not user:
        return jsonify(errno=RET.SESSIONERR,errmsg='用户未登陆')
    #获取参数
    news_id=request.json.get('news_id')
    action=request.json.get('action')
    #检查参数完整性
    if not all([news_id,action]):
        return jsonify(errno=RET.PARAMERR,errmsg='参数错误')
    try:
        news_id=int(news_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.PARAMERR,errmsg='参数类型错误')

    if action not in ['collect','cancel_collect']:
        return jsonify(errno=RET.PARAMERR,errmsg='参数范围错误')

    try:
        news=News.query.get(news_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg='查询新闻数据失败')

    if not news:
        return jsonify(errno=RET.NODATA,errmsg='无新闻数据')

    if action=='collect':
        if news not in user.collection_news:
            user.collection_news.append(news)

    else:
        user.collection_news.remove(news)

    try:
        db.session.add(user)
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR,errmsg='保存数据失败')
    return jsonify(errno=RET.OK,errmsg='OK')



@news_blue.route('/favicon.ico')
def favicon():
    '''
    网站图标加载
    浏览器自动加载，默认访问URL，以获取图标，http://127.0.0.1:5000/favicon.ico
    定义路由，route('/favicon.ico')实现把文件发送给浏览器找到static/news/favicon.ico文件的路径

    代码实现后浏览器无法获取图标的解决方法，清楚浏览器缓存，
    '''
    return current_app.send_static_file('news/favicon.ico')